# -*- coding: utf-8 -*-
import os
import shutil

import wx
import wx.xrc
import wx.dataview
from core.file import File
from gui.operate_dialogs import DeleteFileDialog
from infrastructure.utils import file_util
from infrastructure.utils.id_utils import IdFactory
from gui.new_file_dialog import NewFileDialog


class FileSearchDialog(wx.Dialog):

    context_menu = {}
    def __init__(self, parent, file: File, s:str, type="tree"):
        wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title="检索", pos=wx.DefaultPosition,
                           size=wx.Size(600, 600), style=wx.DEFAULT_DIALOG_STYLE)
        self.SetMaxSize(wx.Size(-1, -1))
        self.type = type
        self.bSizer = wx.BoxSizer(wx.VERTICAL)
        self.file = file

        self.t_search = wx.TextCtrl(self, IdFactory.generate_int_id(), wx.EmptyString, wx.DefaultPosition, wx.Size(-1, 30), wx.TE_PROCESS_ENTER)
        self.t_search.Bind(wx.EVT_TEXT_ENTER, self.to_search)
        self.t_search.Value = s
        self.t_search.SetMaxLength(50)

        self.bSizer.Add(self.t_search, 0, wx.ALIGN_CENTER | wx.EXPAND, 5)

        self.generate_tree(file, s)

        self.SetSizer(self.bSizer)
        self.Bind(wx.dataview.EVT_TREELIST_ITEM_CONTEXT_MENU, self.on_context_menu, id=wx.ID_ANY)


    def generate_tree(self, file: File, s:str):
        if self.file is None or s is None or len(s) == 0:
            return
        self.tree_generate_flag = False
        if not hasattr(self, "tree") or not self.tree:
            self.tree_generate_flag = True
            self.tree = wx.dataview.TreeListCtrl(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize,
                                             wx.dataview.TL_DEFAULT_STYLE)
            isz = (16, 16)
            il = wx.ImageList(isz[0], isz[1])
            self.fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
            self.fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
            self.fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))
            self.smileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))

            self.tree.SetImageList(il)
            self.il = il

            # create some columns
            self.tree.AppendColumn("名称")
            self.tree.AppendColumn("状态")
            self.tree.AppendColumn("更新时间")
            self.tree.AppendColumn("大小")
            self.tree.SetColumnWidth(0, int(self.GetSize()[0] * 0.5))

        self.tree.DeleteAllItems()
        file_list = file.search(s)
        if file_list is not None and len(file_list) > 0:
            for item in file_list:
                child = self.tree.AppendItem(self.tree.GetRootItem(), item.get_name(), data=item)
                self.tree.SetItemText(child, 1, f"{'' if item.is_on_local else '非'}本地-{'' if item.is_on_remote else '非'}远程")
                self.tree.SetItemText(child, 2, str(item.remote_time))
                self.tree.SetItemText(child, 3, str(item.size))
                if item.is_folder:
                    self.tree.SetItemImage(child, self.fldridx)
                    self.tree.SetItemImage(child, self.fldropenidx)
                else:
                    self.tree.SetItemImage(child, self.fileidx)
                    self.tree.SetItemImage(child, self.smileidx)
                if item.is_folder:
                    child1 = self.tree.AppendItem(child, "")
                    self.tree.SetItemText(child1, 1, "")
                    self.tree.SetItemText(child1, 2, "")
                    self.tree.SetItemText(child1, 3, "")
        self.tree.SetItemData(self.tree.GetRootItem(), data=file)
        self.tree.Expand(self.tree.GetRootItem())
        if self.tree_generate_flag:
            self.bSizer.Add(self.tree, 1, wx.EXPAND, 0)
            self.tree.Bind(wx.dataview.EVT_TREELIST_ITEM_EXPANDING, self.treelist_expending, id=self.tree.GetId())
            self.tree.Bind(wx.dataview.EVT_TREELIST_ITEM_ACTIVATED, self.treelist_activated, id=self.tree.GetId())
            self.Layout()

    def treelist_expending(self, event):
        if event.EventObject and event.Item:
            item_data = event.EventObject.GetItemData(event.Item)
            if item_data and item_data.is_folder:
                first_item = event.EventObject.GetFirstChild(event.Item)
                if first_item and not event.EventObject.GetItemData(first_item):
                    self.tree.DeleteItem(first_item)
                first_item = event.EventObject.GetFirstChild(event.Item)
                try:
                    event.EventObject.GetItemData(first_item)
                except:
                    if item_data.get_child_size() > 0:
                        for name, item_child in item_data:
                            child = self.tree.AppendItem(event.Item, item_child.get_name(), data=item_child)
                            self.tree.SetItemText(child, 1, f"{'' if item_child.is_on_local else '非'}本地-{'' if item_child.is_on_remote else '非'}远程")
                            self.tree.SetItemText(child, 2, str(item_child.remote_time))
                            self.tree.SetItemText(child, 3, str(item_child.size))
                            if item_child.is_folder:
                                self.tree.SetItemImage(child, self.fldridx)
                                self.tree.SetItemImage(child, self.fldropenidx)
                            else:
                                self.tree.SetItemImage(child, self.fileidx)
                                self.tree.SetItemImage(child, self.smileidx)
                            if item_child.is_folder:
                                child1 = self.tree.AppendItem(child, "")
                                self.tree.SetItemText(child1, 1, "")
                                self.tree.SetItemText(child1, 2, "")
                                self.tree.SetItemText(child1, 3, "")
                    else:
                        if item_data.is_folder:
                            child1 = self.tree.AppendItem(event.Item, "")
                            self.tree.SetItemText(child1, 1, "")
                            self.tree.SetItemText(child1, 2, "")
                            self.tree.SetItemText(child1, 3, "")

    def treelist_activated(self, event):
        if event.EventObject and event.Item:
            item_data = event.EventObject.GetItemData(event.Item)
            if item_data and item_data.is_folder:
                first_item = event.EventObject.GetFirstChild(event.Item)
                if first_item and not event.EventObject.GetItemData(first_item):
                    self.tree.DeleteItem(first_item)
                first_item = event.EventObject.GetFirstChild(event.Item)
                try:
                    event.EventObject.GetItemData(first_item)
                except:
                    self.refresh(item_data, type = "tree")
            elif item_data and not item_data.is_folder:
                item_data.open()

    def on_context_menu(self, event):
        if not self.context_menu and len(self.context_menu) == 0:
            self.context_menu["打开"] = IdFactory.generate_int_id()
            self.context_menu["新建Markdown"] = IdFactory.generate_int_id()
            self.context_menu["新建文本文档"] = IdFactory.generate_int_id()
            self.context_menu["新建演示文档"] = IdFactory.generate_int_id()
            self.context_menu["新建Excel文档"] = IdFactory.generate_int_id()
            self.context_menu["新建Word文档"] = IdFactory.generate_int_id()
            self.context_menu["新建文件夹"] = IdFactory.generate_int_id()

            self.context_menu["下载"] = IdFactory.generate_int_id()
            self.context_menu["刷新"] = IdFactory.generate_int_id()
            self.context_menu["粘贴"] = IdFactory.generate_int_id()
            self.context_menu["更新/上传"] = IdFactory.generate_int_id()
            self.context_menu["删除"] = IdFactory.generate_int_id()
            self.Bind(wx.EVT_MENU, self.menu_click, id=wx.ID_ANY)
        select_items = self.tree.GetSelections()
        file:File = None
        if select_items and len(select_items) > 0:
            file = self.tree.GetItemData(select_items[0])
        menu = wx.Menu()
        if file is not None:
            menu.Append(self.context_menu["打开"], "打开")
            menu.AppendSeparator()
        menu.Append(self.context_menu["刷新"], "刷新")
        if file is None or file.is_folder:
            if wx.TheClipboard.Open():
                success = wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_FILENAME))
                if success:
                    menu.AppendSeparator()
                    menu.Append(self.context_menu["粘贴"], "粘贴")
            wx.TheClipboard.Close()
        menu .AppendSeparator()
        menu.Append(self.context_menu["下载"], "下载")
        if file is not None:
            menu.Append(self.context_menu["更新/上传"], "更新/上传")
            menu.AppendSeparator()
            menu.Append(self.context_menu["删除"], "删除")
        if file is None or file.is_folder:
            menu.AppendSeparator()
            new_menu = wx.Menu()
            new_menu.Append(self.context_menu["新建文件夹"], "新建文件夹")
            new_menu.AppendSeparator()
            new_menu.Append(self.context_menu["新建文本文档"], "新建文本文档")
            new_menu.Append(self.context_menu["新建Markdown"], "新建Markdown")
            new_menu.Append(self.context_menu["新建演示文档"], "新建演示文档")
            new_menu.Append(self.context_menu["新建Excel文档"], "新建Excel文档")
            new_menu.Append(self.context_menu["新建Word文档"], "新建Word文档")
            menu.AppendMenu(IdFactory.generate_int_id(), '新建', new_menu)

        self.PopupMenu(menu)

    def menu_click(self, event):
        menu_value = None
        for value, id in self.context_menu.items():
            if event.Id == id:
                menu_value = value
                break
        if not menu_value:
            return
        else:
            {
                "tree": self.treelist_process(menu_value)
            }[self.type]

    def treelist_process(self, command: str):
        select_items = self.tree.GetSelections()
        root_file = self.tree.GetItemData(self.tree.GetRootItem())
        select_items = select_items if select_items and len(select_items) > 0 else [self.tree.GetRootItem()]
        if select_items and len(select_items) > 0:
            for item in select_items:
                file: File = self.tree.GetItemData(item)
                if file:
                    if command == "打开":
                        file.open()
                    elif command.startswith("新建"):
                        NewFileDialog(self, self.suffix_dict.get(command, "text"), file=file, root_file=root_file, is_folder=True if command == "新建文件夹" else False).Show()
                    elif command == "下载":
                        file.download()
                        self.refresh(root_file, type="tree")
                    elif command == "刷新":
                        file.refresh()
                        self.refresh(root_file, type="tree")
                    elif command == "更新/上传":
                        file.upload_or_update()
                        self.refresh(root_file, type="tree")
                    elif command == "删除":
                        DeleteFileDialog(self, file, root_file=root_file).Show()
                    elif command == "粘贴":
                        self.paste_file(file)
                        self.refresh(root_file, type="tree")

    def delete_file(self, file:File):
        """
        删除文件并刷新页面
        :param file:
        :return:
        """
        file.delete()

    def paste_file(self, file: File):
        if file.is_folder:
            file_path_list = list()
            if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():
                success = wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_FILENAME))
                if success:
                    file_obj = wx.FileDataObject()
                    if wx.TheClipboard.GetData(file_obj):
                        value = file_obj.GetFilenames()
                        if value is not None and len(value) > 0:
                            file_path_list = file_path_list + value
            wx.TheClipboard.Close()
            if file_path_list is not None and len(file_path_list) > 0:
                for file_path in file_path_list:
                    file_util.copy(file_path, file.get_path())

    def to_search(self, event):
        self.generate_tree(self.file, event.String)